package com.game.avatar
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.BlendMode;
	import flash.display.DisplayObject;
	import flash.display.MovieClip;
	import flash.filters.BitmapFilter;
	import flash.geom.ColorTransform;
	import flash.geom.Matrix;
	import flash.utils.Dictionary;

	/**
	 * 普通动画类，动画由一组帧图片构成
	 * @author hyy
	 *
	 */
	public class Animation
	{
		/**
		 * 当前动画帧
		 */
		public var curFrame : Frame;
		/**
		 * 总帧数
		 */
		public var frameCount : int;
		private var _frames : Array = [];
		/**
		 * 临时的动画时间
		 */
		protected var tmpElapsedTime : int;
		/**
		 * 当前动画已持续的时间
		 */
		public var curAnimationDurations : int;
		/**
		 * 当前的动画帧索引
		 */
		public var curFrameIndex : int;
		/**
		 * 是否暂停播放
		 */
		public var isPaused : Boolean;
		/**
		 * 当前帧是否到最后一帧
		 */
		public var isEnd : Boolean;
		/**
		 *  是否播放次数结束
		 */
		public var isLoopEnd : Boolean;
		/**
		 * 动画总共需要循环的次数
		 */
		public var loops : int = 0;
		/**
		 * 当前已经循环的次数
		 */
		public var curLoop : int = 0;

		public var filters : Array = [];

		public function Animation()
		{
		}

		/**
		 * 跳到第几帧
		 */
		public function gotoFrame(index : int) : Frame
		{
			var frameCount : int = frameCount - 1;

			if(index < 0)
				index = 0;
			curFrameIndex = index;

			if(frameCount < 0 || index > frameCount)
				return null;

			isEnd = index == frameCount;
			curFrame = _frames[index];
			return curFrame;
		}

		/**
		 * 添加帧
		 * @param frame
		 * @param index 在指定位置添加帧
		 *
		 */
		public function addFrame(frame : Frame, index : int = -1) : void
		{
			if(index == -1)
				index = frameCount;

			if(_frames)
			{
				_frames.splice(index, 0, frame);
				frameCount = _frames.length;
			}
		}

		/**
		 * 获得帧
		 * @param index
		 * @return
		 *
		 */
		public function getFrame(index : int) : Frame
		{
			if(index < 0 || index >= frameCount)
				return null;

			return _frames[index];
		}

		/**
		 * 动画帧序列
		 */
		public function get frames() : Array
		{
			return _frames;
		}

		/**
		 * @private
		 */
		public function set frames(value : Array) : void
		{
			_frames = value;

			if(_frames)
				frameCount = _frames.length;
		}

		/**
		 * 设置每个动作的持续时间
		 * @param duration
		 *
		 */
		public function setDration(duration : int) : void
		{
			if(duration <= 0)
				return;

			for each(var frame : Frame in _frames)
			{
				frame.duration = duration;
			}
		}

		/**
		 * 获取下一帧，如果动画暂停，返回当前帧
		 * @param elapsedTime 帧时间
		 * @param addFrameDuration 附加间隔
		 * @return 返回当前播放的帧
		 */
		public function tryNext(elapsedTime : int, addFrameDuration : int = 0) : Frame
		{
			if(!curFrame)
				return gotoFrame(0);

			if(isPaused)
				return curFrame;

			if(addFrameDuration == 0)
				addFrameDuration = curFrame.duration;

			tmpElapsedTime += elapsedTime;
			curAnimationDurations += elapsedTime;

			//如果该帧停留的次数超过了定义的次数，获取下一帧
			if(tmpElapsedTime < addFrameDuration)
				return curFrame;
			//要强制跳的帧数
			var skipFrames : int = tmpElapsedTime / addFrameDuration;

			if(skipFrames >= 2)
			{
				var tmpCurFrameIndex : int = curFrameIndex;

				//大于一帧的跳帧情况
				do
				{
					tmpElapsedTime -= addFrameDuration;
					tmpCurFrameIndex += 1;

					if(tmpCurFrameIndex >= frameCount)
					{
						tmpCurFrameIndex = 0;
					}
					addFrameDuration = getFrame(tmpCurFrameIndex).duration;
				} while(tmpElapsedTime >= addFrameDuration)
			}
			else
			{
				//求余值 
				tmpElapsedTime %= addFrameDuration;
			}
			curFrameIndex += skipFrames;

			//如果播放到动画尾，重新从第一帧开始播放
			if(curFrameIndex >= frameCount)
			{
				curLoop++;
				isEnd = true;
				//从0帧开始跳转 当前帧索引 相对于 总帧数 的余数
				curFrameIndex = curFrameIndex % frameCount;

				//如果需要记录结束 ，则不跳转
				if(loops != 0 && curLoop >= loops)
				{
					tmpElapsedTime += curFrameIndex * addFrameDuration;
					gotoFrame(frameCount - 1);
					isLoopEnd = true;
				}
				else
				{
					curAnimationDurations = 0;
				}
			}
			else
			{
				isEnd = false;
			}
			gotoFrame(curFrameIndex);
			return curFrame;
		}

		public function createAnimationFrames(movie : MovieClip, duration : int = 120) : void
		{
			if(!movie)
				return;
			var i : int;
			var frame : Frame;
			var bmp : Bitmap;
			var bmd : BitmapData;
			var child : DisplayObject;

			for(i = 1; i <= movie.totalFrames; i++)
			{
				frame = new Frame();
				movie.gotoAndStop(i);

				bmd = null;

				if(movie.numChildren > 0)
				{
					child = movie.getChildAt(0);
					bmp = child as Bitmap;

					if(bmp)
					{
						bmd = bmp.bitmapData;
					}
					else
					{
						bmd = new BitmapData(child.width, child.height, true, 0);
						bmd.draw(child);
					}
				}
				frame.data = bmd;

				if(child)
				{
					frame.offsetX = child.x;
					frame.offsetY = child.y;
				}
				frame.duration = duration;
				addFrame(frame, i);
			}
		}

		/**
		 * 重置动画
		 *
		 */
		public function resetAnimation() : void
		{
			isEnd = false;
			isPaused = false;
			isLoopEnd = false;
			curLoop = 0;
			curFrameIndex = 0;
			tmpElapsedTime = 0;
			curAnimationDurations = 0;
		}

		/**
		 * 释放内存
		 * @param value 是否完全释放内存
		 *
		 */
		public function destroy(value : Boolean = false) : void
		{
			if(value)
			{
				var frame : Frame;

				for each(frame in _frames)
				{
					frame.destory();
				}
			}

			if(_frames)
			{
				_frames.length = 0;
			}
			curFrame = null;
			resetAnimation();
		}

		public function clone() : Animation
		{
			var animation : Animation = new Animation();
			animation.filters = filters;
			animation.frames = [].concat(_frames);
			return animation;
		}

	}
}